home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
lang
/
mc302
/
dosutil
/
diff.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-03-18
|
5KB
|
224 lines
/*
* Displays differences between two ASCII files
*
* Options:
* -d = Inhibit display of differences
* -l = Inhibit display of line numbers
* r=num = Minimum # lines to re-syncronize
*
* Copyright 1988-1994 Dave Dunfield
* All rights reserved.
*
* Permission granted for personal (non-commercial) use only.
*
* Compile command: cc diff -fop
*/
#include <stdio.h>
#define LINE_SIZE 100 /* maximum size of input lines */
#define MAX_DIFF 200 /* maximum number of different lines */
char ft1[MAX_DIFF][LINE_SIZE], ft2[MAX_DIFF][LINE_SIZE];
unsigned r1 = 0, r2 = 0, w1 = 0, w2 = 0, l1, l2;
unsigned resync = 2, diffs = 0;
char diff = -1, line = -1;
char *fn1, *fn2;
FILE *fp1, *fp2;
/*
* Main program, compare files
*/
main(argc, argv)
int argc;
char *argv[];
{
char *ptr;
l2 = 0;
for(l1 = 1; l1 < argc; ++l1) {
ptr = argv[l1];
switch((tolower(*ptr++) << 8) | tolower(*ptr++)) {
case 'r=' : /* minimum # lines to resync */
resync = get_num(ptr);
break;
case '-d' : /* inhibit display of differences */
diff = 0;
break;
case '-l' : /* inhibit display of line numbers */
line = 0;
break;
default: /* filename to compare */
if(!(fp2 = fopen(fn2 = argv[l1], "r"))) {
fprintf(stderr, "%s: Unable to open\n", fn2);
exit(-1); }
if(!l2++) {
fn1 = fn2;
fp1 = fp2; } } }
if(l2 != 2) {
fputs("\nUse: diff <file1> <file2> [-d -l r=#lines]\n\nCopyright 1988-1994 Dave Dunfield\nAll rights reserved.\n", stderr);
exit(-1); }
l1 = l2 = 1;
for(;;) {
fill_buffer();
if((r1 == w1) || (r2 == w2)) {
show_changed(w1, w2);
if(diffs)
fprintf(stdout,"%u differences.\n", diffs);
else
fprintf(stdout,"Files match exactly.\n");
exit(diffs); }
if(equal(ft1[r1], ft2[r2])) {
r1 = (r1 + 1) % MAX_DIFF;
r2 = (r2 + 1) % MAX_DIFF;
++l1; ++l2;
continue; }
scan_buffer(); }
}
/*
* Fill up the buffer with lines from the input file
*/
fill_buffer()
{
register int j1, j2;
while((j1 = (w1 + 1) % MAX_DIFF) != r1) {
if(!fgets(ft1[w1], LINE_SIZE, fp1))
break;
w1 = j1; }
while((j2 = (w2 + 1) % MAX_DIFF) != r2) {
if(!fgets(ft2[w2], LINE_SIZE, fp2))
break;
w2 = j2; }
}
/*
* Scan the buffer looking for a pattern
*/
scan_buffer()
{
int i, i1, i2, j1, j2;
char flag;
i1 = r1;
i2 = r2;
fill_buffer();
do { /* scan with this portion */
j1 = i1;
j2 = i2;
do {
flag = 0;
if(j2 != w2) { /* we can check this one */
flag = -1;
if(equal(ft1[i1], ft2[j2]) && (i=test_next(i1, j2))) {
show_changed(i1, j2);
r1 = (r1 + i) % MAX_DIFF;
r2 = (r2 + i) % MAX_DIFF;
l1 += i; l2 += i;
return; }
j2 = (j2 + 1) % MAX_DIFF; }
if(j1 != w1) { /* we can check this one */
flag = -1;
if(equal(ft1[j1], ft2[i2]) && (i=test_next(j1, i2))) {
show_changed(j1, i2);
r1 = (r1 + i) % MAX_DIFF;
r2 = (r2 + i) % MAX_DIFF;
l1 += i; l2 += i;
return; }
j1 = (j1 + 1) % MAX_DIFF; } }
while(flag);
if(i1 != w1) { /* More lines in buffer */
i1 = (i1 + 1) % MAX_DIFF;
flag = -1; }
if(i2 != w2) { /* More lines in buffer */
i2 = (i2 + 1) % MAX_DIFF;
flag = -1; } }
while(flag);
/* Cannot accept any more data into buffers, check for overflow */
if((((w1 + 1) % MAX_DIFF) == r1) || (((w2 + 1) % MAX_DIFF) == r2)) {
fprintf(stdout,"Differences to great at %u < > %u\n", l1, l2);
exit(-1); }
/* Buffers not full, must be end of file */
show_changed(w1, w2);
}
/*
* Test that the next "resync" entries match
*/
test_next(i1, i2)
unsigned i1, i2;
{
int i;
for(i=1; i < resync; ++i) {
i1 = (i1 + 1) % MAX_DIFF;
i2 = (i2 + 1) % MAX_DIFF;
if((i1 == w1) || (i2 == w2))
return i;
if(!equal(ft1[i1], ft2[i2]))
return 0; }
return i;
}
/*
* Display the changed lines & reset read pointers
*/
show_changed(i1, i2)
unsigned i1, i2;
{
if((r1 != i1) || (r2 != i2)) {
++diffs;
if(line)
fprintf(stdout,"*** %s(%u) < > %s(%u) ***\n", fn1, l1, fn2, l2);
while(r1 != i1) {
++l1;
if(diff)
fprintf(stdout,"<%s\n", ft1[r1]);
r1 = (r1 + 1) % MAX_DIFF; }
while(r2 != i2) {
++l2;
if(diff)
fprintf(stdout,">%s\n", ft2[r2]);
r2 = (r2 + 1) % MAX_DIFF; } }
}
/*
* Get a decimal number from the command line
*/
get_num(string)
char *string;
{
register unsigned value;
register char chr;
value = 0;
while(isdigit(chr = *string++))
value = (value * 10) + (chr - '0');
if(chr) {
fputs("DIFF: Invalid number\n", stderr);
exit(-1); }
return value;
}
/*
* Test for two strings equal
*/
equal(str1, str2)
char *str1, *str2;
{
register char c;
while((c = *str1++) == *str2++) {
if(!c)
return 1; }
return 0;
}